package com.cwd.arm.domain.entity;

import com.alibaba.fastjson.JSONObject;
import com.cwd.arm.common.enums.MsgTypeEnum;
import com.cwd.arm.common.util.AviatorEvaluatorUtil;
import com.cwd.arm.common.util.BigDecimalUtil;
import com.cwd.arm.common.util.DateUtil;
import com.cwd.arm.domain.entity.base.MsgReEntity;
import com.cwd.arm.domain.entity.vo.msg.ReceivceEndMsgVo;
import lombok.Data;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Description:收款节点
 * Created on 2021年11月16日
 *
 * @author yan
 */
@Data
public class ReceiveNodeEntity implements MsgReEntity{

    /**
     *
     */
    private Long id;

    /**
     * 项目id
     */
    private Long projectId;

    /**
     * 项目名称
     */
    private String projectName;

    /**
     * 收款节点名称
     */
    private String nodeName;

    /**
     * 收款类型
     */
    private String type;

    /**
     * 收款条件
     */
    private String nodeCondition;

    /**
     * 收款截止日期
     */
    private java.util.Date endDate;

    /**
     * 收款进度
     */
    private BigDecimal completionRate;

    /**
     * 应收金额
     */
    private BigDecimal receivableAmount;

    /**
     * 结算金额
     */
    private BigDecimal closeAmount;

    /**
     * 已收金额
     */
    private java.math.BigDecimal receivedAmount;

    private List<TaxEntity> diffTaxEntityList;

    private TaxEntity newTaxEntity;

    private TaxEntity oldTaxEntity;

    /**
     * 未收款
     */
    private BigDecimal unReceivedAmount;

    /**
     * 回退操作
     */
    public void undo() {
        receivableAmount = BigDecimalUtil.minus(receivableAmount);
        receivedAmount = BigDecimalUtil.minus(receivedAmount);
        closeAmount = BigDecimalUtil.minus(closeAmount);
    }

    public boolean canDel() {
        if (BigDecimalUtil.hasRecord(receivedAmount)) {
            return false;
        }
        return true;
    }

    public boolean canAdd(BigDecimal contractAmount, BigDecimal projectReceivableAmount) {
        if (BigDecimalUtil.hasRecord(receivableAmount) && BigDecimalUtil.hasRecord(completionRate)) {
            return vailRateAmount(contractAmount, projectReceivableAmount, receivableAmount);
        }
        return true;
    }

    public boolean canUpdate(BigDecimal contractAmount, BigDecimal projectReceivableAmount, BigDecimal oldReceivableAmount) {
        if (BigDecimalUtil.hasRecord(receivableAmount) && BigDecimalUtil.hasRecord(completionRate)) {
            BigDecimal diffReceivableAmount = BigDecimalUtil.sub(receivableAmount, oldReceivableAmount);
            return vailRateAmount(contractAmount, projectReceivableAmount, diffReceivableAmount);
        }
        return true;
    }


    public void addTax(TaxEntity taxEntity) {
        receivedAmount = BigDecimalUtil.add(receivedAmount, taxEntity.getReceivedAmount());
        newTaxEntity = taxEntity;
    }

    public void updateTax(TaxEntity oldTaxEntity, TaxEntity newTaxEntity) {
        newTaxEntity.init(oldTaxEntity);
        oldTaxEntity.undo();
        BigDecimal diffReceivedAmount = BigDecimalUtil.add(oldTaxEntity.getReceivedAmount(), newTaxEntity.getReceivedAmount());
        receivedAmount = BigDecimalUtil.add(receivedAmount, diffReceivedAmount);
        this.newTaxEntity = newTaxEntity;
        this.oldTaxEntity = oldTaxEntity;
    }

    public void delTax(TaxEntity taxEntity) {
        taxEntity.undo();
        receivedAmount = BigDecimalUtil.add(receivedAmount, taxEntity.getReceivedAmount());
        newTaxEntity = taxEntity;
    }

    public List<TaxEntity> getDiffTaxEntityList() {
        diffTaxEntityList = new ArrayList<>(2);
        if (newTaxEntity != null) {
            diffTaxEntityList.add(newTaxEntity);
        }
        if (oldTaxEntity != null) {
            diffTaxEntityList.add(oldTaxEntity);
        }
        return diffTaxEntityList;
    }

    /**
     * 初始化金额,如果为null默认设置旧金额
     * @param oldReceiveNodeEntity
     */
    public void initAmount(ReceiveNodeEntity oldReceiveNodeEntity){
        if(oldReceiveNodeEntity !=null){
            if(receivableAmount == null){
                receivableAmount = oldReceiveNodeEntity.getReceivableAmount();
            }
            if(receivedAmount == null){
                receivedAmount = oldReceiveNodeEntity.getReceivedAmount();
            }
            if(closeAmount == null){
                closeAmount = oldReceiveNodeEntity.getCloseAmount();
            }
        }
    }

    public void initEndDate(ReceiveNodeEntity oldReceiveNodeEntity){
        if(oldReceiveNodeEntity !=null){
            if(endDate == null){
                endDate = oldReceiveNodeEntity.getEndDate();
            }
        }
    }

    public BigDecimal getTaxUnreceiveAmount() {
        return getDiffTaxEntityList().stream().map(TaxEntity::getTaxUnreceiveAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
    }

    @Override
    public String getContent(MsgTypeEnum msgTypeEnum) {
        if(MsgTypeEnum.RECEVICE_END == msgTypeEnum){
            return "项目'"+projectName+"'"+"截止日期为'"+DateUtil.dateToDateStr(endDate)+"'的'"+nodeName+"'节点还有"+BigDecimalUtil.format(unReceivedAmount)+"万元未收到";
        }
        return "";
    }

    @Override
    public String getMsgParam(MsgTypeEnum msgTypeEnum) {
        if(MsgTypeEnum.RECEVICE_END == msgTypeEnum){
            return JSONObject.toJSONString(new ReceivceEndMsgVo(projectName,DateUtil.dateToDateStr(endDate),nodeName,BigDecimalUtil.format(unReceivedAmount)));
        }
        return "";
    }

    @Override
    public boolean isMatch(MsgTypeEnum msgTypeEnum) {
        if(MsgTypeEnum.RECEVICE_END == msgTypeEnum){
            if(DateUtil.differentDaysByMillisecond(endDate,new Date()) > 0){
                if(BigDecimalUtil.hasRecord(closeAmount)){
                    unReceivedAmount = BigDecimalUtil.sub(closeAmount,receivedAmount);
                }else{
                    unReceivedAmount = BigDecimalUtil.sub(receivableAmount,receivedAmount);
                }
                if(unReceivedAmount.compareTo(BigDecimal.ZERO) > 0){
                    return true;
                }
            }
        }
        return false;
    }

    private boolean vailRateAmount(BigDecimal contractAmount, BigDecimal projectReceivableAmount, BigDecimal diffReceivableAmount) {
        BigDecimal rate = getRate(contractAmount, projectReceivableAmount, diffReceivableAmount);
        if (BigDecimalUtil.scaleRate(rate).compareTo(BigDecimalUtil.scaleRate(completionRate)) == 0) {
            return true;
        }
        return false;
    }

    private BigDecimal getRate(BigDecimal contractAmount, BigDecimal projectReceivableAmount, BigDecimal diffReceivableAmount) {
        BigDecimal newProjectReceivableAmount = BigDecimalUtil.add(projectReceivableAmount, diffReceivableAmount);
        return BigDecimalUtil.div2(newProjectReceivableAmount, contractAmount);
    }


}
